Opportunity Youth are people ages 16-24 who are neither working nor in school. A series of feature articles by Mandy McLaren in the Courier-Journal has ignited discussion around opportunity youth, sometimes also called disconnected youth. In addition to the feature articles there is also a report by Kentuckiana Works digging into even more of the data around opportunity youth.
Here, we take a slighlty closer look at opportunity youth in Louisville/Jefferson County (most reporting has focused on the Metro Level, which includes neighboring counties). One reason for this shift is because most of the solutions discussed focus on either city government or JCPS. A separate analysis of surrounding counties would be a useful follow up, but the core county and it’s surrounding counties are very different in terms of both underlying problems and solutions.
#initial setup of data
library(tidyverse)
library(survey)
library(plotly)
# read in data and filter to just Louisville where school and employment aren't NA
df <- read_csv("ipums_discon.csv") %>%
filter(PUMA %in% c(01701, 01702, 01703, 01704, 01705, 01706) &
STATEFIP == 21 &
EMPSTAT != 0 &
SCHOOL != 0) %>%
#recode employment, school, and create disconnected youth. Having dichotomous variables makes it easy to get percentages later
mutate(emp = if_else(EMPSTAT == 1, 1, 0),
school = if_else(SCHOOL == 2, 1, 0),
discon = if_else((emp == 0 & school == 0), 1, 0))
Opportunity Youth are those neither in school or work, and the balance between school and work shifts by age. Enrollment is very high among 16 and 17 year olds (who are legally required to be in school, so this may mask students who are technically enrolled but chronically absent). Ages 18 through 20 show a drastic drop in school enrollment, followed by another drop at 22. Employment follows the opposite pattern, rising steadily with only 20% of 16 year olds employed and going up to 80% of 24 year olds. Unfortunately, school enrollment drops off more quickly than employment rising, leading to disconnection peaking at age 20.
svy_df <- svydesign(ids = ~1, weights = ~PERWT, data = df)
emp_school <- svyby(~emp+school+discon, ~AGE, design = svy_df, svymean)
df_plt <- emp_school %>%
mutate(emp = round(emp * 100, 1),
school = round(school * 100, 1),
discon = round(discon * 100, 1))
plt_line <- plot_ly(df_plt, x = ~AGE) %>%
add_trace(y = ~emp, name = 'Employed', type = 'scatter', mode = 'lines',
line = list(color = 'blue')) %>%
add_trace(y = ~school, name = 'In School', type = 'scatter', mode = 'lines',
line = list(color = 'green')) %>%
add_trace(y = ~discon, name = 'Disconnected', type = 'scatter', mode = 'lines',
line = list(color = 'red')) %>%
layout(title = "Disconnected Youth in Jefferson County by Age, 2014-2018",
yaxis = list(title = "Percent"),
xaxis = list(title = "Age"))
plt_line
Two things to learn from this graph
Because 16-18 year olds tend to be in school and have much lower rates of disconnection, this more detailed look focuses on ages 19-24. The chart above just considered school and employment without considering overlap. Over a quarter of 19-24 year olds in Louisville are actually both in school and working.
df5_19 <- df %>%
filter(YEAR > 2013 & AGE > 18) #19-24 for the past 5 years
df5_19 <- df5_19 %>%
mutate(status = case_when(
emp == 1 & school == 1 ~ "Employed and in school",
emp == 1 & school == 0 ~ "Employed, not in school",
emp == 0 & school == 1 ~ "In school, not employed",
emp == 0 & school == 0 ~ "Disconnected"
),
count = 1)
svy_df5_19 <- svydesign(ids = ~1, weights = ~PERWT, data = df5_19)
emp_school5_19 <- svyby(~count, ~status, design = svy_df5_19, svytotal) %>%
mutate(percent = count / sum(count))
plt_donut <- plot_ly(data = emp_school5_19, labels = ~status, values = ~percent,
marker = list(colors = c('red', 'cyan', 'blue', 'green'))) %>%
add_pie(hole = 0.6) %>%
layout(title = "Youth in Louisville aged 19-24, 2014-2018",
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
plt_donut
We can also look among those who are disconnected to see if they are out of the labor force and if they worked any weeks in the past year. This serves as a rough proxy for what we might consider short-term disconnected (in labor force and worked not long ago) and long-term disconnected who may be harder to reach. Just under half of disconnected youth did not work
#a deeper dive on disconnected youth
df_discon <- df5_19 %>%
filter(status == "Disconnected") #350 observations
df_discon <- df_discon %>%
mutate(labforce = if_else(LABFORCE == 2, 1, 0),
workedly = if_else(WORKEDYR == 3, 1, 0),
statusd = case_when(
labforce == 1 & workedly == 1 ~ "Worked LY, In Labor Force",
labforce == 0 & workedly == 1 ~ "Worked LY, Not in Labor Force",
labforce == 1 & workedly == 0 ~ "Didn't work LY, In Labor Force",
labforce == 0 & workedly == 0 ~ "Didn't Work LY, Not in Labor Force"
),
count = 1)
svy_discon <- svydesign(ids = ~1, weights = ~PERWT, data = df_discon)
df_discon <- svyby(~count, ~statusd, design = svy_discon, svytotal) %>%
mutate(percent = count / sum(count))
plt_donut <- plot_ly(data = df_discon, labels = ~statusd, values = ~percent) %>%
add_pie(hole = 0.6) %>%
layout(title = "Disconnected Youth in Louisville aged 19-24, 2014-2018",
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
plt_donut
Looking over time also shows impact of the recession, with employment falling and school enrollment rates rising when the economy is poor. However, for the most part, the percentage of disconnected youth has fallen since the 2012. (The large swings from year to year are due to small sample size)
#Analysis by Year for 19-24
df <- df %>%
filter(AGE > 18)
svy_df <- svydesign(ids = ~1, weights = ~PERWT, data = df)
emp_school <- svyby(~emp+school+discon, ~YEAR, design = svy_df, svymean)
df_plt <- emp_school %>%
mutate(emp = round(emp * 100, 1),
school = round(school * 100, 1),
discon = round(discon * 100, 1))
plt_line <- plot_ly(df_plt, x = ~YEAR) %>%
add_trace(y = ~emp, name = 'Employed', mode = 'lines',
line = list(color = 'blue')) %>%
add_trace(y = ~school, name = 'In School', mode = 'lines',
line = list(color = 'green')) %>%
add_trace(y = ~discon, name = 'Disconnected', mode = 'lines',
line = list(color = 'red')) %>%
layout(title = "Disconnected Youth in Jefferson County by Year",
yaxis = list(title = "Percent"),
xaxis = list(title = "Year"))
plt_line
Having a high school degree makes a large difference. For those 19-24 who do have a high school degree (or GED) the percent employed rises to around 80 percent. Important context here is that 80% is the percent of people 25-54 who are working. Whether or not 80% of the prime working age labor force being employed is a good number is a more detailed question for economists and sociologists, but for our purposes here we can say they’ve effectively transitioned into the adult population.
#Analysis by AGE for 19-24 who get HS degree
df_hs <- df %>%
filter(AGE > 18 & EDUCD != 999 & EDUCD > 62)
svy_df <- svydesign(ids = ~1, weights = ~PERWT, data = df_hs)
emp_school <- svyby(~emp+school+discon, ~AGE, design = svy_df, svymean)
df_plt <- emp_school %>%
mutate(emp = round(emp * 100, 1),
school = round(school * 100, 1),
discon = round(discon * 100, 1))
plt_line <- plot_ly(df_plt, x = ~AGE) %>%
add_trace(y = ~emp, name = 'Employed', mode = 'lines',
line = list(color = 'blue')) %>%
add_trace(y = ~school, name = 'In School', mode = 'lines',
line = list(color = 'green')) %>%
add_trace(y = ~discon, name = 'Disconnected', mode = 'lines',
line = list(color = 'red')) %>%
layout(title = "Disconnected Youth in Jefferson County by Year",
yaxis = list(title = "Percent"),
xaxis = list(title = "Year"))
plt_line
By contrast nearly half of those who do not graduate high school wind up disconnected - the numbers bounce around a little since in any given year there aren’t that many 22 year olds who don’t have a H.S. degree included in the survey, but the contrast between those who do and don’t graduate is stark.
#Analysis by AGE for 19-24 who do not get a HS degree
df_no_hs <- df %>%
filter(AGE > 18 & EDUCD != 999 & EDUCD < 62)
svy_df <- svydesign(ids = ~1, weights = ~PERWT, data = df_no_hs)
emp_school <- svyby(~emp+school+discon, ~AGE, design = svy_df, svymean)
df_plt <- emp_school %>%
mutate(emp = round(emp * 100, 1),
school = round(school * 100, 1),
discon = round(discon * 100, 1))
plt_line <- plot_ly(df_plt, x = ~AGE) %>%
add_trace(y = ~emp, name = 'Employed', mode = 'lines',
line = list(color = 'blue')) %>%
add_trace(y = ~school, name = 'In School', mode = 'lines',
line = list(color = 'green')) %>%
add_trace(y = ~discon, name = 'Disconnected', mode = 'lines',
line = list(color = 'red')) %>%
layout(title = "Disconnected Youth in Jefferson County by Year",
yaxis = list(title = "Percent"),
xaxis = list(title = "Year"))
plt_line
df5_19 <- df %>%
filter(YEAR > 2013 & AGE > 18 & EDUCD != 999) #19-24 for the past 5 years
df5_19 <- df5_19 %>%
mutate(hs = case_when(
EDUCD > 62 ~ "HS Degree or GED",
TRUE ~ "No HS Degree or GED"
),
status = case_when(
emp == 1 & school == 1 ~ "Employed and in school",
emp == 1 & school == 0 ~ "Employed, not in school",
emp == 0 & school == 1 ~ "In school, not employed",
emp == 0 & school == 0 ~ "Disconnected"
),
count = 1) %>%
filter(status == "Disconnected")
svy_df5_19 <- svydesign(ids = ~1, weights = ~PERWT, data = df5_19)
emp_school5_19 <- svyby(~count, ~hs, design = svy_df5_19, svytotal) %>%
mutate(percent = count / sum(count))
plt_donut <- plot_ly(data = emp_school5_19, labels = ~hs, values = ~percent,
marker = list(colors = c('green', 'red'))) %>%
add_pie(hole = 0.6) %>%
layout(title = "Opportunity Youth in Louisville aged 19-24, 2014-2018",
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
plt_donut
df5_19 <- df %>%
filter(YEAR > 2013 & AGE > 18 & FERTYR != 0 & FERTYR != 8 & SEX == 2) #19-24 for the past 5 years, fertility question asked only to women
df5_19 <- df5_19 %>%
mutate(child = case_when(
FERTYR == 2 ~ "Child in last year",
TRUE ~ "No Child in last year"
),
status = case_when(
emp == 1 & school == 1 ~ "Employed and in school",
emp == 1 & school == 0 ~ "Employed, not in school",
emp == 0 & school == 1 ~ "In school, not employed",
emp == 0 & school == 0 ~ "Disconnected"
),
count = 1) %>%
filter(status == "Disconnected")
svy_df5_19 <- svydesign(ids = ~1, weights = ~PERWT, data = df5_19)
emp_school5_19 <- svyby(~count, ~child, design = svy_df5_19, svytotal) %>%
mutate(percent = count / sum(count))
plt_donut <- plot_ly(data = emp_school5_19, labels = ~child, values = ~percent,
marker = list(colors = c('blue', 'orange'))) %>%
add_pie(hole = 0.6) %>%
layout(title = "Opportunity Youth in Louisville aged 19-24, 2014-2018",
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
plt_donut